package com.nsn.vs.sdm.util.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class UtilReflection {
	
    @SuppressWarnings("unchecked")
    public static <T> T getFieldValue(String field, Object o) {
        Field f = getField(field, o);
        try {
            return (T) f.get(o);
        } catch (Exception e) {
            return null;
        }
    }

    public static void setFieldValue(String field, Object o, Object value) {
        Field f = getField(field, o);
        try {
            f.set(o, value);
        } catch (Exception e) {
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T invokeMethod(String method, Object o, Class<?>[] paramTypes, Object... params) {
        Method m = getMethod(method, o, paramTypes);
        try {
            return (T) m.invoke(o, params);
        } catch (Exception e) {
            return null;
        }
    }
    
    public static Field[] getFields (Object o) {
    	Class<?> c;
        if (o instanceof Class<?>) {
            c = (Class<?>) o;
        } else {
            c = o.getClass();
        }
        return c.getDeclaredFields();
    }
    
    private static Field getField(String field, Object o) {
        Class<?> c;
        if (o instanceof Class<?>) {
            c = (Class<?>) o;
        } else {
            c = o.getClass();
        }
        
        Field f = null;
        do {
            try {
                f = c.getDeclaredField(field);
                break;
            } catch (NoSuchFieldException e) {
                c = c.getSuperclass();
            }
        } while (c != null);
        if (f == null) {
            throw new IllegalArgumentException("No such field: " + field + " in " + o);
        }
        f.setAccessible(true);
        return f;
    }

    private static Method getMethod(String method, Object o, Class<?>... paramTypes) {
        Class<?> c;
        if (o instanceof Class<?>) {
            c = (Class<?>) o;
        } else {
            c = o.getClass();
        }

        Method m = null;
        do {
            try {
                m = c.getDeclaredMethod(method, paramTypes);
                break;
            } catch (NoSuchMethodException e) {
                c = c.getSuperclass();
            }
        } while (c != null);
        if (m == null) {
            throw new IllegalArgumentException("No such method: " + method + " in " + o);
        }
        m.setAccessible(true);
        return m;
    }
}
